/*
 * foreach.h
 *
 *  Created on: 2008-9-25
 *      Author: fanliangliang
 */

#ifndef TEST_FOREACH_H_
#define TEST_FOREACH_H_

#include "toxic.h"
#include <vector>
#include <list>
#include <deque>
#include <string>
#include <iostream>

using namespace std;
using namespace toxic;

static void test_foreach1() {

	vector<int> v;
	for (int i = 0; i < 5; ++i) {
		v.push_back(i);
	}

	// Iterate over a vector by value
	foreach (int i, v) {
		cout << i << ", ";
	}
	cout << endl;

	// Output: 0, 1, 2, 3, 4,


	// Iterate over a vector by reference
	foreach (int& i, v) {
		// Modify the underlying sequence
		i += 1;
		cout << i << ", ";
	}
	cout << endl;

	// Output: 1, 2, 3, 4, 5,


	// Iterate over a vector by const reference
	foreach (const int& i, v) {
		// Can not modify the underlying sequence here
		//i += 1;
		cout << i << ", ";
	}
	cout << endl;

	// Output: 1, 2, 3, 4, 5,
}

static void test_foreach2() {

	deque<int> d;
	for (int i = 0; i < 5; ++i) {
		d.push_back(i);
	}

	// Predeclare the loop variable,
	// and use continue, break, and return in the loop body
	int i = 0;
	foreach (i, d) {
		if (i == 0) continue;
		if (i == 1) break;
		if (i == 2) return;
	}
}

static void test_foreach3() {

	list<string> vss;
	vss.push_back("hello ");
	vss.push_back("world");

	const list<string>& vs = vss;

	// Iterate over a vector of strings with nested foreach loops
	foreach (const string& s, vs) {
		foreach (char c, s) {
			cout << c;
		}
	}
	cout << endl;

	// Output: hello world


	// In this example, notices that braces around the loop body are not necessary
	foreach (const string& s, vs)
		foreach (char c, s)
			cout << c;

	cout << endl;

	// Output: hello world
}

static void test_foreach4() {

	// Iterate over an array
	short x[] = { 1, 2, 3, 4, 5 };

	foreach (int i, x) {
		// The short was implicitly converted to an int
		cout << i << ", ";
	}

	cout << endl;

	// Output: 1, 2, 3, 4, 5,
}

void do_test_foreach() {

	cout << "***** foreach *****" << endl;

	test_foreach1();
	test_foreach2();
	test_foreach3();
	test_foreach4();
}

#endif /* TEST_FOREACH_H_ */
